/**
 *  Copyright (C) 2008-2013  Telosys project org. ( http://www.telosys.org/ )
 *
 *  Licensed under the GNU LESSER GENERAL PUBLIC LICENSE, Version 3.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *          http://www.gnu.org/licenses/lgpl.html
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package org.telosys.util;

/**
 * Utility class for types conversions ( set of static methods )<br>
 * Primitive types conversion with MIN/MAX values management
 * 
 * @author Laurent GUERIN
 * 
 */
public class Conv
{
    public final static boolean STRICT = true ;
    public final static boolean CUT = false ;
    
    //-----------------------------------------------------------------------------------
    /**
     * Private constructor to avoid instance creation
     */
    private Conv()
    {    
    }
    
    //-----------------------------------------------------------------------------------
    /**
     * Checks the given value is between the min and max values (min and max included)
     * @param val
     * @param sType
     * @param min
     * @param max
     * @param strict if true a TelosysRuntimeException is throwned if the value is out of min/max limits
     * @return the valid value in the given bounds
     */
    private static long checkMinMax(long val, String sType, long min, long max, boolean strict )
    {
        if ( val < min )
        {
            if ( strict )
            {
                throw new RuntimeException("Cannot convert to " + sType + " : value lower than MIN ( " + val + " < " + min + " )" );
            }
            else
            {
                return min ;
            }
        }
        if ( val > max )
        {
            if ( strict )
            {
                throw new RuntimeException("Cannot convert to " + sType + " : value greater than MAX ( " + val + " > " + max + " )" );
            }
            else
            {
                return max ;
            }
        }
        return val;
    }
    
    //-----------------------------------------------------------------------------------
    /**
     * Converts to char strictly ( throws a TelosysRuntimeException if lower/greater than MIN/MAX )
     * @param l : value to convert
     * @return the resulting char 
     * @since v 1.0.2
     */
    public static char toChar(long l)
    {
        return (char) checkMinMax(l, "char", Character.MIN_VALUE, Character.MAX_VALUE, STRICT );
    }
    
    /**
     * Converts to char ( STRICT or CUT mode )
     * @param l : value to convert
     * @param b : mode :<br>
     * STRICT = throws a TelosysRuntimeException if lower/greater than MIN/MAX<br>
     * CUT = no exception ( just cut the value if necessary, returning MIN or MAX )
     * @return the resulting char
     * @since v 1.0.2
     */
    public static char toChar(long l, boolean b)
    {
        return (char) checkMinMax(l, "char", Character.MIN_VALUE, Character.MAX_VALUE, b );
    }
        
    //-----------------------------------------------------------------------------------
    /**
     * Converts to byte strictly ( throws a TelosysRuntimeException if lower/greater than MIN/MAX )
     * @param l : value to convert
     * @return the resulting value
     */
    public static byte toByte(long l)
    {
        return (byte) checkMinMax(l, "byte", Byte.MIN_VALUE, Byte.MAX_VALUE, STRICT );
    }
    
    /**
     * Converts to byte ( STRICT or CUT mode )
     * @param l : value to convert
     * @param b : mode :<br>
     * STRICT = throws a TelosysRuntimeException if lower/greater than MIN/MAX<br>
     * CUT = no exception ( just cut the value if necessary, returning MIN or MAX )
     * @return the resulting value
     */
    public static byte toByte(long l, boolean b)
    {
        return (byte) checkMinMax(l, "byte", Byte.MIN_VALUE, Byte.MAX_VALUE, b );
    }
    
    //-----------------------------------------------------------------------------------
    /**
     * Converts to short strictly ( throws a TelosysRuntimeException if lower/greater than MIN/MAX )
     * @param l : value to convert
     * @return the resulting value
     */
    public static short toShort(long l)
    {
        return (short) checkMinMax(l, "short", Short.MIN_VALUE, Short.MAX_VALUE, STRICT );
    }
    
    /**
     * Converts to short ( STRICT or CUT mode )
     * @param l : value to convert
     * @param b : mode :<br>
     * STRICT = throws a TelosysRuntimeException if lower/greater than MIN/MAX<br>
     * CUT = no exception ( just cut the value if necessary, returning MIN or MAX )
     * @return the resulting value
     */
    public static short toShort(long l, boolean b)
    {
        return (short) checkMinMax(l, "short", Short.MIN_VALUE, Short.MAX_VALUE, b );
    }
    
    //-----------------------------------------------------------------------------------
    /**
     * Converts to int strictly ( throws a TelosysRuntimeException if lower/greater than MIN/MAX )
     * @param l : value to convert
     * @return the resulting value
     */
    public static int toInt(long l)
    {
        return (int) checkMinMax(l, "int", Integer.MIN_VALUE, Integer.MAX_VALUE, STRICT );
    }
    
    /**
     * Converts to int ( STRICT or CUT mode )
     * @param l : value to convert
     * @param b : mode :<br>
     * STRICT = throws a TelosysRuntimeException if lower/greater than MIN/MAX<br>
     * CUT = no exception ( just cut the value if necessary, returning MIN or MAX )
     * @return the resulting value
     */
    public static int toInt(long l, boolean b)
    {
        return (int) checkMinMax(l, "int", Integer.MIN_VALUE, Integer.MAX_VALUE, b );
    }

}
